package com.shark.uh.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.shark.uh.enums.RoleStatus;
import com.shark.uh.enums.ResponseCode;
import com.shark.uh.exception.BusinessException;
import com.shark.uh.model.dto.roles.RoleDTO;
import com.shark.uh.model.dto.roles.RoleRemoveDTO;
import com.shark.uh.model.dto.roles.RoleSetDTO;
import com.shark.uh.model.dto.roles.RolesResponseDTO;
import com.shark.uh.model.entity.User;
import com.shark.uh.model.query.role.AssignedRolesQuery;
import com.shark.uh.model.query.role.AssignedUsersQuery;
import com.shark.uh.model.vo.RoleCreatorVO;
import com.shark.uh.model.vo.RoleVO;
import com.shark.uh.model.vo.UserVO;
import com.shark.uh.utils.CharacterChecker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shark.uh.model.entity.Roles;
import com.shark.uh.service.RolesService;
import com.shark.uh.mapper.RolesMapper;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 *
 */
@Service
@Log4j2
public class RolesServiceImpl extends ServiceImpl<RolesMapper, Roles>
        implements RolesService {

    @Resource
    private RolesMapper rolesMapper;

    /**
     * 获取角色创建者列表
     *
     * @return 角色创建者列表
     */
    @Override
    public List<RoleCreatorVO>getCreators() {

        // 查询
        List<User> creatorList = rolesMapper.selectCreator();

        // 数据转换
        ArrayList<RoleCreatorVO> roleCreatorVOS = new ArrayList<>();
        for (User user : creatorList) {
            roleCreatorVOS.add(new RoleCreatorVO(user));
        }

        return roleCreatorVOS;

    }


    /**
     * 条件查询角色列表
     *
     * @param roleName      角色名称
     * @param creatorUserId 创建者ID
     * @param status        角色状态
     * @param pageNo        页号
     * @param pageSize      每页条数的大小
     * @param sortBy        排序规则
     * @return 角色列表
     */
    @Override
    public List<RoleDTO> listConditional(String roleName, String creatorUserId, String status, Integer pageNo, Integer pageSize, String sortBy) {
        // 记录操作开始日志
        log.info("开始查询角色列表，查询参数：{}");


        // 查询
        List<RoleDTO> roleDTOList = rolesMapper.list(
                StringUtils.isBlank(roleName) ? null : roleName,
                StringUtils.isBlank(creatorUserId) ? null : Long.parseLong(creatorUserId),
                StringUtils.isBlank(status) ? null : status,
                (pageNo - 1) * pageSize,
                pageSize,
                sortBy);

        log.info("查询成功，查询条数：{}", roleDTOList.size());
        return roleDTOList;
    }


    /**
     * 创建角色
     *
     * @param roleName    角色名称
     * @param description 描述
     */
    @Transactional
    @Override
    public void save(String roleName, String description) {
        // 记录操作开始日志
        log.info("开始创建角色，角色名称：{}", roleName);

        // 参数合法性校验
        if (CharacterChecker.containsInvalidCharacters(roleName)) {
            throw new BusinessException(ResponseCode.INVALID_PARAMETER, "角色名称包含非法字符");
        }

        // 数据准备
        Roles role = new Roles();
        role.setName(roleName);
        role.setDescription(description);
        role.setCreatorUserId(StpUtil.getLoginIdAsLong());
        role.setStatus(RoleStatus.ACTIVE.getStatus());

        // 插入数据（捕获唯一约束异常）
        try {
            rolesMapper.insert(role);
        } catch (DuplicateKeyException e) {
            log.info("角色名 {} 已存在", roleName);
            throw new BusinessException(ResponseCode.DATA_ALREADY_EXISTS, "角色名已存在");
        }

        log.info("角色 {} 创建成功，操作人ID：{}", roleName, StpUtil.getLoginIdAsLong());

    }

    /**
     * 删除角色
     *
     * @param roleId 角色ID
     */
    @Transactional
    @Override
    public void remove(Long roleId) {
        // 记录操作开始日志
        log.info("开始删除角色，角色ID：{}", roleId);

        // 删除角色
        ArrayList<Long> ids = new ArrayList<>();
        ids.add(roleId);
        int deleteCount = rolesMapper.updateStatusBatch(ids, RoleStatus.DELETED.getStatus());

        // 删除失败
        if (deleteCount == 0) {
            log.info("删除角色失败，角色ID：{}", roleId);
            throw new BusinessException(ResponseCode.INVALID_PARAMETER, "角色ID不存在");
        }

        log.info("角色 {} 删除成功，操作人ID：{}", roleId, StpUtil.getLoginIdAsLong());
    }

    /**
     * @param roleIds
     * @param userIds
     */
    @Override
    public void assign(List<Long> roleIds, List<Long> userIds) {

    }


    /**
     * 更新角色信息 （描述）
     *
     * @param roleId         角色ID
     * @param newDescription 新描述
     */
    @Override
    public void update(String roleId, String newDescription) {
        // 记录操作开始日志
        log.info("开始更新角色，更新内容：{}", roleId + newDescription);

        // 更新数据
        Long roleIdL = Long.parseLong(roleId);
        int rows = rolesMapper.updateDescription(roleIdL, newDescription);

        // 更新失败
        if (rows == 0) {
            log.info("更新角色失败，角色ID：{}", roleId);
            throw new BusinessException(ResponseCode.DATA_UPDATE_FAIL);
        }

        log.info("角色 {} 更新成功，操作人ID：{}", roleId, StpUtil.getLoginIdAsLong());

    }


    @Override
    public List<UserVO> listAssignedUsers(AssignedUsersQuery queryParams) {

        // 查询参数处理
        long roleId = Long.parseLong(queryParams.getRoleId());
        String roleStatus = queryParams.getStatus();
        int offset = (queryParams.getPageNo() - 1) * queryParams.getPageSize();
        int limit = queryParams.getPageSize();

        // 查询
        List<User> users = rolesMapper.selectUsersByRoleId(roleId, roleStatus, offset, limit);

        // 查询结果处理
        List<UserVO> userVOS = new ArrayList<>();
        for (User user : users) {
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(user, userVO);
            userVOS.add(userVO);
        }

        return userVOS;
    }


    /**
     * 获取用户的所有角色
     *
     * @param userId 用户ID
     * @return RolesResponseDTO
     */
    @Override
    public List<Roles> listAssignedRoles(AssignedRolesQuery query) {
        List<Roles> roles = rolesMapper.selectByUserId(Long.parseLong(query.getUserId()), 0, 10);
        List<RoleVO> roleVOS = new ArrayList<>();
        for (Roles role : roles) {
            RoleVO roleVO = new RoleVO();
            BeanUtils.copyProperties(role, roleVO);
            roleVOS.add(roleVO);
        }
        RolesResponseDTO rolesResponseDTO = new RolesResponseDTO();
        rolesResponseDTO.setRoles(roleVOS);
        return roles;
    }

    /**
     * 禁用角色
     *
     * @param roleIds
     */
    @Override
    public void banRole(List<Long> roleIds) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("roleIds", roleIds);
        params.put("status", RoleStatus.BANNED.getStatus());
        rolesMapper.updateStatusBatch(roleIds, RoleStatus.BANNED.getStatus());
    }

    /**
     * 解禁角色
     *
     * @param roleIds
     */
    @Override
    public void unbanRole(List<Long> roleIds) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("roleIds", roleIds);
        params.put("status", RoleStatus.BANNED.getStatus());
        rolesMapper.updateStatusBatch(roleIds, RoleStatus.BANNED.getStatus());
    }

    /**
     * 为用户绑定角色
     *
     * @param roleSetDTO
     */
    @Override
    public void addRoleForUser(RoleSetDTO roleSetDTO) {
        rolesMapper.insetRelationBatch(roleSetDTO.getUserId(), roleSetDTO.getRoleIds());
    }

    /**
     * 删除用户某个角色
     *
     * @param roleRemoveDTO
     */
    @Override
    public void deleteRoleFromUser(RoleRemoveDTO roleRemoveDTO) {
        rolesMapper.deleteRelationBatch(roleRemoveDTO.getUserId(), roleRemoveDTO.getRoleIds());
    }
}




